global loader           ; making entry point visible to linker
extern main             ; kmain is defined elsewhere

; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ  1<<0                   ; align loaded modules on page boundaries
MEMINFO     equ  1<<1                   ; provide memory map
FLAGS       equ  MODULEALIGN | MEMINFO  ; this is the Multiboot 'flag' field
MAGIC       equ    0x1BADB002           ; 'magic number' lets bootloader find the header
CHECKSUM    equ -(MAGIC + FLAGS)        ; checksum required

section .text
align 4
MultiBootHeader:
   dd MAGIC
   dd FLAGS
   dd CHECKSUM

; reserve initial kernel stack space
STACKSIZE equ 0x4000                  ; that's 16k.

loader:
   cli;
   
   lgdt[GDT_SEL];
   mov esp, 0x7C00                    ; set up the stack
   push eax                           ; pass Multiboot magic number
   push ebx                           ; pass Multiboot info structure

   call  main                         ; call kernel proper
   hlt                                ; halt machine should kernel return

; ==========  GDT Segment Selector  ==========
align 4
GDT_SEL:
    dw GDT_DESC_END-GDT_DESC-1
    dd GDT_DESC
    
; ========== GDT Segment Descriptor ========== 
align 8 
GDT_DESC:
  .NULL:   
    dq 0x0000000000000000               ; null segment
  .CODE32:
    dq 0x00CF9A000000FFFF               ; limit = 4GB, D/B = 32-bit, DPL = 0, type = code r/w
  .DATA32:
    dq 0x00CF92000000FFFF               ; limit = 4GB, D/B = 32-bit, DPL = 0, type = data r/w
GDT_DESC_END:

